<?php
namespace app\common\shopify;

use think\facade\Config;
use think\facade\Log;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\RequestException;

class BaseClient {
    protected $shopUrl;
    protected $accessToken;
    protected $apiVersion ;
    protected $guzzleClient;

    public function __construct() {
        $config = Config::get('shopify');
        $this->shopUrl = "https://{$config['shop_name']}.myshopify.com";
        $this->accessToken = $config['access_token'];
        $this->apiVersion = $config['api_version'];

        // 创建精简的Guzzle客户端实例
        $this->guzzleClient = new GuzzleClient([
            'timeout' => 60.0,       // 总请求超时时间
            'connect_timeout' => 15, // 连接阶段超时（TCP+SSL握手）[6](@ref)
            'verify' => false,        // 保持SSL证书验证（生产环境必需）[2](@ref)
            'http_errors' => true,   // 启用HTTP错误处理
        ]);
    }

    /**
     * 发送GraphQL请求
     * @param string $query GraphQL查询语句
     * @param array $variables 请求变量
     * @return array
     */
    public function graphqlRequest(string $query, array $variables = []): array {
        $url = "{$this->shopUrl}/admin/api/{$this->apiVersion}/graphql.json";
        $payload = [
            'query' => $query,
            'variables' => $variables
        ];

        try {
            $response = $this->httpPost($url, $payload);
            $data = json_decode($response->getBody(), true);

            if (!empty($data['errors'])) {
                Log::error('[shopify] API错误: '.json_encode($data['errors']));
                throw new \Exception('Shopify API Error');
            }
            return $data['data'] ?? [];
        } catch (RequestException $e) {
            $errorMsg = $e->getMessage();
            Log::error("Shopify请求失败: {$errorMsg}");
            throw new \Exception('Guzzle Error: '.$errorMsg);
        } catch (\Exception $e) {
            Log::error("Shopify请求失败: {$e->getMessage()}");
            throw $e;
        }
    }

    /**
     * 使用Guzzle发送POST请求
     * @param string $url 请求URL
     * @param array $payload 请求数据
     * @return \Psr\Http\Message\ResponseInterface
     */
    private function httpPost(string $url, array $payload) {
        try {
            return $this->guzzleClient->post($url, [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'X-Shopify-Access-Token' => $this->accessToken,
                ],
                'json' => $payload,
                // 强制使用TLS 1.2协议保证安全连接[1](@ref)
                'curl' => [
                    CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
                ]
            ]);
        } catch (RequestException $e) {
            $logContext = [
                'method' => 'POST',
                'url' => $url,
                'timeout' => $e->getHandlerContext()['total_time'] ?? 0,
                'curl_errno' => $e->getHandlerContext()['errno'] ?? 0,
                'response' => $e->hasResponse() ? (string)$e->getResponse()->getBody() : null
            ];
            Log::error('Shopify请求异常: ' . json_encode($logContext));
            throw $e;
        }
    }
}